#include "EditorOutputAbilityModel.h"

#include "Output/Console.h"

REditorOutputAbilityModel::REditorOutputAbilityModel()
{
    Lines.Reserve(InitialMemorySize);

    RConsole::Get()->OnPrint.Add(this,&REditorOutputAbilityModel::OnPrint);
}

void REditorOutputAbilityModel::PostLoadFromAsset()
{
    Super::PostLoadFromAsset();

    int64_t NewCapacity = (Lines.Num()/InitialMemorySize+1)*InitialMemorySize;
    Lines.Reserve(NewCapacity);
}

void REditorOutputAbilityModel::AddLine(const CString &InLine)
{
    if(Lines.Empty() ||  Lines.Last().EndsWith(U'\n') )
    {
        if((Lines.Num()+1)>=Lines.Capacity())
        {
            Lines.Reserve(Lines.Capacity()+InitialMemorySize);
        }

        Lines.Add(InLine);

        OnLineNumChanged.ExecuteIfBound();
    }
    else
    {
        //append to last line
        Lines.Last()+=InLine;
    }

    if(bAutoScroll)
    {
        ScrollPercent=1.f;
    }
}

void REditorOutputAbilityModel::ClearLines()
{
    Lines.Clear(false);
    OnLineNumChanged.ExecuteIfBound();
}

void REditorOutputAbilityModel::OnPrint(const CString & InNewMessage)
{
    CString NewMessage = InNewMessage;
    int64_t EndIndex=-1;
    do{
        EndIndex=NewMessage.Find(U'\n');
        if(EndIndex!=-1)
        {
            AddLine(NewMessage.Left(EndIndex+1));
            NewMessage=NewMessage.Right(NewMessage.GetLength()-EndIndex-1);
        }
    }
    while(EndIndex!=-1);

    if(!NewMessage.IsEmpty())
    {
        AddLine(NewMessage);
    }
}
